﻿using Microsoft.Extensions.DependencyInjection;
using ZeroBug.EasyFlow.Communication;
using ZeroBug.EasyFlow.Core;
using ZeroBug.EasyFlow.Machine;

namespace ZeroBug.EasyFlow.Step
{
    public class TcpClientSendStep : IStep
    {
        public bool IsSingleRun { get; set; }
        public bool IgnoreChildren { get; set; }
        public string Icon { get; set; } = "Network";
        public int ChildrenIndex { get; set; }
        public Core.Step? NextStep { get; set; }

        public void RegisterVariables(FlowBase flow, ZeroBug.EasyFlow.Core.Step step)
        {
            if (flow.GetFlowManager().VariableManager.GetVariable($"{step.Description}.Recv") == null)
            {
                Variable receivedVar = new Variable($"{step.Description}.Recv", string.Empty, VariableType.Text);
                receivedVar.GetCurrentValues = () =>
                {
                    string[] ss = packages.Select(sp => sp.ReceivedData).ToArray();
                    return ss;
                };
                flow.GetFlowManager().VariableManager.AddVariable(receivedVar, VariableFrom.Local);
            }
        }

        VariableExpression sendVar;
        VariableExpression startPattern;
        VariableExpression endPattern;
        VariableExpression tcpClientName;
        CommunicationClient client;
        public bool Compile(FlowBase flow, ZeroBug.EasyFlow.Core.Step step, out string errInfo)
        {
            errInfo = string.Empty;

            if(!step.Parameters.ContainsKey("SendMessage"))
            {
                errInfo = "不存在SendMessage变量";
                return false;
            }

            return true;
        }
        public object GetForm()
        {
            throw new NotImplementedException();
        }

        public StepInfo GetInfo()
        {
            StepInfo info = new StepInfo();
            info.StepName = "TcpClientSend";
            info.Group = StepGroup.Communication;
            info.ImagePath = "pack://application:,,,/ZeroBug.EasyFlow.Step;component/Images/条件.png";
            return info;
        }

        public void OnChildrenEnter()
        {
            throw new NotImplementedException();
        }

        public void OnChildrenLeave()
        {
            throw new NotImplementedException();
        }

        public bool Prepare(FlowBase flow, ZeroBug.EasyFlow.Core.Step step, out string errInfo)
        {
            errInfo = string.Empty;

            sendVar = step.Parameters["SendMessage"];
            startPattern = step.Parameters["StartPattern"];
            endPattern = step.Parameters["EndPattern"];
            tcpClientName = step.Parameters["TcpClientName"];
            client = LocalMachine.Services.GetService<MachineResource<CommunicationClient, ICommunicationClient>>()!.Value![tcpClientName.GetEquivalent()[0]];

            client.EmptyBuffer();

            return true;
        }

        List<SendPackage<string>> packages;
        public StepResult Run(FlowBase flow, ZeroBug.EasyFlow.Core.Step step, out string errInfo)
        {
            errInfo = string.Empty;

            packages = new List<SendPackage<string>>();

            for (int i = 0; i < sendVar.GetEquivalent().Count; i++)
            {
                SendPackage<string> sp = new SendPackage<string>();
                sp.Message = sendVar.GetEquivalent()[i];
                sp.StartPattern = startPattern.GetEquivalent()[i];
                sp.EndPattern = endPattern.GetEquivalent()[i];
                packages.Add(sp);
            }
            foreach(SendPackage<string> package in packages)
            {
                client.Send<string>(package);
                if(!package.Wait(500000, flow.IsBreak))
                {
                    errInfo = "发送后接收超时";
                    return StepResult.Failure;
                }
                client.Remove<string>(package);
            }

            return StepResult.Success;
        }

        public string GetTip(Core.Step step)
        {
            return "";
        }

        public (SerializableDictionary<string, VariableExpression>, List<VariableJudge>) GetParametersAndConditions()
        {
            throw new NotImplementedException();
        }

        public void UnRegisterVariables(FlowBase flow, Core.Step step)
        {
        }
    }
}
